package com.mall.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mall.dao.UserMapper;
import com.mall.entity.User;
import com.mall.service.impl.UserServicelmpl;
import com.mall.utils.UploadUtil;
import com.mall.utils.UserCache;
import com.mall.vo.WebResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import javax.validation.Valid;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserServicelmpl userService;

    @Autowired
    private UserMapper userMapper;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @ResponseBody
    @GetMapping("/log")
    public void loginPage(User user,HttpServletResponse response) throws IOException {

        response.setCharacterEncoding("UTF-8");
        WebResult login = userService.login(user);
        String token = (String) login.getData();
        if (token!=null){
            login.setData(null);
            response.setHeader("token",token);
            response.getWriter().write(JSON.toJSONString(login));
        }else {
            response.getWriter().write(JSON.toJSONString(login));
        }
    }

    @ResponseBody
    @GetMapping("/reg")
    public WebResult<Object> regPage(@Valid User user, String code,BindingResult bindingResult){
        //校验用户信息完整
        if (bindingResult.hasErrors()){
            Map<String,String> error= new HashMap<>();
            for (FieldError fieldError : bindingResult.getFieldErrors()) {
                error.put(fieldError.getField(),fieldError.getDefaultMessage());
            }
            return WebResult.builder().data(error).code(202).message("用户格式错误").build();
        }
        //校验验证码
        if (code==null){
            return WebResult.builder().code(202).message("验证码为空").build();
        }
        String s = stringRedisTemplate.opsForValue().get(WebResult.SMS_CODE_CHANGE_PREFIX + user.getEmail());
        if (s==null){
            return WebResult.builder().code(202).message("验证码与邮箱不匹配").build();
        }
        if (!StringUtils.isEmpty(s)&&code.equals(s.split("_")[0])){

            //对密码进行加密
            BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
            String encode = passwordEncoder.encode(user.getPassword());
            //将加密密码替换原来的明文
            user.setPassword(encode);
            //检查用户是否存在
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("email",user.getEmail());
            User selectOne = userMapper.selectOne(queryWrapper);
            if (selectOne!=null){
                return WebResult.builder().code(318).message("用户已存在").build();
            }
            userMapper.insert(user);
            //删除验证码
            stringRedisTemplate.delete(WebResult.SMS_CODE_CHANGE_PREFIX + user.getEmail());
        }else {
            return WebResult.builder().code(303).message("验证码错误").build();
        }
        return WebResult.builder().code(200).message("注册成功").build();
    }
    @ResponseBody
    @GetMapping("/sms")
    public WebResult sendCode(@RequestParam("email") String email){
        // TODO: 2022/8/23 接口防刷
        String rcode = stringRedisTemplate.opsForValue().get(WebResult.SMS_CODE_CHANGE_PREFIX + email);
        //能获取到，说明之前发过了
        if (rcode!=null){
            //取出时间，进行检查
            long l = Long.parseLong(rcode.split("_")[1]);
            //还在十分钟之内，直接返回
            if (System.currentTimeMillis() - l <60000){
                return WebResult.builder().code(403).message("发送验证码频率太高，稍后尝试").build();
            }
        }
        //生产随机验证码,后加上系统的时间，为了防止60s内再次获取验证码
        String code = UUID.randomUUID().toString().substring(0, 4)+"_"+System.currentTimeMillis();
        //redis缓存验证码
        stringRedisTemplate.opsForValue().set(WebResult.SMS_CODE_CHANGE_PREFIX+email,code,10, TimeUnit.MINUTES);
        //发送验证码
        return userService.sendcode(email,code);
    }
    @ResponseBody
    @GetMapping("/avatar")
    public WebResult editoravatar(Part image){
        String url = null;
        try {
             url = UploadUtil.updateFileOnLine(image);
             return WebResult.builder().code(200).message("上传头像成功").data(url).build();
        } catch (IOException e) {
            e.printStackTrace();
            return WebResult.builder().code(507).message("上传头像失败").build();
        }
    }
    @ResponseBody
    @GetMapping("/editor")
    public WebResult editorUser(User user){
        User u = UserCache.get();
        return userService.editor(user, u.getId());
    }
}
